/*
 * This program is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later
 * version.
 * 
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 * 
 * You should have received a copy of the GNU General Public License along with
 * this program. If not, see <http://www.gnu.org/licenses/>.
 */
package com.l2emu.gameserver.handler.itemhandlers;

import java.util.logging.Logger;

import com.l2emu.Config;
import com.l2emu.gameserver.datatables.SkillTable;
import com.l2emu.gameserver.handler.IItemHandler;
import com.l2emu.gameserver.model.L2Effect;
import com.l2emu.gameserver.model.L2ItemInstance;
import com.l2emu.gameserver.model.L2Skill;
import com.l2emu.gameserver.model.actor.L2Character;
import com.l2emu.gameserver.model.actor.L2Playable;
import com.l2emu.gameserver.model.actor.L2Summon;
import com.l2emu.gameserver.model.actor.instance.L2PcInstance;
import com.l2emu.gameserver.model.actor.instance.L2PetInstance;
import com.l2emu.gameserver.model.entity.events.CTF;
import com.l2emu.gameserver.model.entity.events.DM;
import com.l2emu.gameserver.model.entity.events.TvT;
import com.l2emu.gameserver.model.entity.events.VIP;
import com.l2emu.gameserver.network.SystemMessageId;
import com.l2emu.gameserver.network.serverpackets.ActionFailed;
import com.l2emu.gameserver.network.serverpackets.SystemMessage;
import com.l2emu.gameserver.templates.skills.L2EffectType;



/**
 * 
 * temp handler
 * here u can found items that yet cannot be unhardcoded due to missing better core support
 *
 */
public class Potions implements IItemHandler
{
	protected static final Logger _log = Logger.getLogger(Potions.class.getName());

	private static final int[] ITEM_IDS =
	{
		// General Potions
		727, 728, 1060, 1061, 1073,
		// Fisherman Potions
		8193, 8194, 8195, 8196, 8197, 8198, 8199, 8200, 8201,
		// Echo Crystals (why? - using same skill id, not supported yet from core to destroy used item from skill use)
		4416,7061,
		// Kamael Soul Bottles
		10410,10411,10412,
		// Fruit Potions
		20393,20394,
		// chatm of courage
		8515,8516,8517,8518,8519,8520,
		// battleground buffs
		10143,10144,10145,10146,10147,10148
	};

	/**
	 * @see com.l2emu.gameserver.handler.IItemHandler#useItem(com.l2emu.gameserver.model.actor.L2Playable, com.l2emu.gameserver.model.L2ItemInstance)
	 */
	public synchronized void useItem(L2Playable playable, L2ItemInstance item)
	{
		L2PcInstance activeChar; // use activeChar only for L2PcInstance checks where cannot be used PetInstance

		boolean res = false;

		if (playable instanceof L2PcInstance)
			activeChar = (L2PcInstance) playable;
		else if (playable instanceof L2PetInstance)
			activeChar = ((L2PetInstance) playable).getOwner();
		else
			return;

		if ((activeChar._inEventTvT && TvT._started && !Config.TVT_ALLOW_POTIONS) || (activeChar._inEventCTF && CTF._started && !Config.CTF_ALLOW_POTIONS)
				|| (activeChar._inEventDM && DM._started && !Config.DM_ALLOW_POTIONS) || (activeChar._inEventVIP && VIP._started && !Config.VIP_ALLOW_POTIONS))
		{
			playable.sendPacket(ActionFailed.STATIC_PACKET);
			return;
		}

		if (activeChar.isInOlympiadMode())
		{
			activeChar.sendPacket(new SystemMessage(SystemMessageId.THIS_ITEM_IS_NOT_AVAILABLE_FOR_THE_OLYMPIAD_EVENT));
			return;
		}

		int itemId = item.getItemId();

		switch (itemId)
		{
			
			case 728: // Custom mana potion, xml: 9008
				res = usePotion(activeChar, 9008, 1);
				break;
			case 727: // Healing_potion, xml: 2032
			case 1061:
				if (!isEffectReplaceable(playable, L2EffectType.HEAL_OVER_TIME, itemId))
					return;
				res = usePotion(playable, 2032, 1);
				break;
			case 1060: // Lesser Healing Potion
			case 1073: // Beginner's Potion, xml: 2031
				if (!isEffectReplaceable(activeChar, L2EffectType.HEAL_OVER_TIME, itemId))
					return;
				res = usePotion(playable, 2031, 1);
				break;
/*
Control of this needs to be moved back into potions.java so proper message support can be handled for specific events.
			case 10409: // Empty Bottle of Souls
				if (activeChar.getActiveClass() >= 123 && activeChar.getActiveClass() <= 136) //Kamael classes only
				{
					if (activeChar.getSouls() >= 6)
						res = usePotion(activeChar, 2498, 1);
					else
						playable.sendPacket(new SystemMessage(SystemMessageId.THERE_IS_NOT_ENOUGH_SOUL));
				}
				else
					playable.sendPacket(new SystemMessage(SystemMessageId.NOTHING_HAPPENED));
				break;
*/
			case 10410: // 5 Souls Bottle
				if (activeChar.getActiveClass() >= 123 && activeChar.getActiveClass() <= 136) // Kamael classes only
					res = usePotion(activeChar, 2499, 1);
				else
					playable.sendPacket(new SystemMessage(SystemMessageId.NOTHING_HAPPENED));
				break;
			case 10411: // 5 Souls Bottle Combat
				if (activeChar.getActiveClass() >= 123 && activeChar.getActiveClass() <= 136 && activeChar.isInsideZone(L2Character.ZONE_SIEGE)) //Kamael classes only
					res = usePotion(activeChar, 2499, 1);
				else
					playable.sendPacket(new SystemMessage(SystemMessageId.NOTHING_HAPPENED));
				break;
			case 10412: // 10 Souls Bottle
				if (activeChar.getActiveClass() >= 123 && activeChar.getActiveClass() <= 136) //Kamael classes only
					res = usePotion(activeChar, 2499, 2);
				else
					playable.sendPacket(new SystemMessage(SystemMessageId.NOTHING_HAPPENED));
				break;
			case 8193: // Fisherman's Potion - Green
				if (!(playable instanceof L2PcInstance))
				{
					itemNotForPets(activeChar);
					return;
				}
				if (activeChar.getSkillLevel(1315) <= 3)
				{
					playable.destroyItem("Consume", item.getObjectId(), 1, null, false);
					playable.sendPacket(new SystemMessage(SystemMessageId.NOTHING_HAPPENED));
					return;
				}
				usePotion(playable, 2274, 1);
				break;
			case 8194: // Fisherman's Potion - Jade
				if (!(playable instanceof L2PcInstance))
				{
					itemNotForPets(activeChar);
					return;
				}
				if (activeChar.getSkillLevel(1315) <= 6)
				{
					playable.destroyItem("Consume", item.getObjectId(), 1, null, false);
					playable.sendPacket(new SystemMessage(SystemMessageId.NOTHING_HAPPENED));
					return;
				}
				usePotion(playable, 2274, 2);
				break;
			case 8195: // Fisherman's Potion - Blue
				if (!(playable instanceof L2PcInstance))
				{
					itemNotForPets(activeChar);
					return;
				}
				if (activeChar.getSkillLevel(1315) <= 9)
				{
					playable.destroyItem("Consume", item.getObjectId(), 1, null, false);
					playable.sendPacket(new SystemMessage(SystemMessageId.NOTHING_HAPPENED));
					return;
				}
				usePotion(playable, 2274, 3);
				break;
			case 8196: // Fisherman's Potion - Yellow
				if (!(playable instanceof L2PcInstance))
				{
					itemNotForPets(activeChar);
					return;
				}
				if (activeChar.getSkillLevel(1315) <= 12)
				{
					playable.destroyItem("Consume", item.getObjectId(), 1, null, false);
					playable.sendPacket(new SystemMessage(SystemMessageId.NOTHING_HAPPENED));
					return;
				}
				usePotion(playable, 2274, 4);
				break;
			case 8197: // Fisherman's Potion - Orange
				if (!(playable instanceof L2PcInstance))
				{
					itemNotForPets(activeChar);
					return;
				}
				if (activeChar.getSkillLevel(1315) <= 15)
				{
					playable.destroyItem("Consume", item.getObjectId(), 1, null, false);
					playable.sendPacket(new SystemMessage(SystemMessageId.NOTHING_HAPPENED));
					return;
				}
				usePotion(playable, 2274, 5);
				break;
			case 8198: // Fisherman's Potion - Purple
				if (!(playable instanceof L2PcInstance))
				{
					itemNotForPets(activeChar);
					return;
				}
				if (activeChar.getSkillLevel(1315) <= 18)
				{
					playable.destroyItem("Consume", item.getObjectId(), 1, null, false);
					playable.sendPacket(new SystemMessage(SystemMessageId.NOTHING_HAPPENED));
					return;
				}
				usePotion(playable, 2274, 6);
				break;
			case 8199: // Fisherman's Potion - Red
				if (!(playable instanceof L2PcInstance))
				{
					itemNotForPets(activeChar);
					return;
				}
				if (activeChar.getSkillLevel(1315) <= 21)
				{
					playable.destroyItem("Consume", item.getObjectId(), 1, null, false);
					playable.sendPacket(new SystemMessage(SystemMessageId.NOTHING_HAPPENED));
					return;
				}
				usePotion(playable, 2274, 7);
				break;
			case 8200: // Fisherman's Potion - White
				if (!(playable instanceof L2PcInstance))
				{
					itemNotForPets(activeChar);
					return;
				}
				if (activeChar.getSkillLevel(1315) <= 24)
				{
					playable.destroyItem("Consume", item.getObjectId(), 1, null, false);
					playable.sendPacket(new SystemMessage(SystemMessageId.NOTHING_HAPPENED));
					return;
				}
				usePotion(playable, 2274, 8);
				break;
			case 8201: // Fisherman's Potion - Black
				if (!(playable instanceof L2PcInstance))
				{
					itemNotForPets(activeChar);
					return;
				}
				usePotion(playable, 2274, 9);
				break;
			case 20393: // Sweet Fruit Cocktail
				res = usePotion(playable, 22056, 1);
				usePotion(playable, 22057, 1);
				usePotion(playable, 22058, 1);
				usePotion(playable, 22059, 1);
				usePotion(playable, 22060, 1);
				usePotion(playable, 22061, 1);
				usePotion(playable, 22064, 1);
				usePotion(playable, 22065, 1);
				break;
			case 20394: // Fresh Fruit Cocktail
				res = usePotion(playable, 22062, 1);
				usePotion(playable, 22063, 1);
				usePotion(playable, 22065, 1);
				usePotion(playable, 22066, 1);
				usePotion(playable, 22067, 1);
				usePotion(playable, 22068, 1);
				usePotion(playable, 22069, 1);
				usePotion(playable, 22070, 1);
				break;
			case 4416:
			case 7061:
				res = usePotion(playable, 2073, 1);
				break;
			case 8515:
			case 8516:
			case 8517:
			case 8518:
			case 8519:
			case 8520:
				res = usePotion(playable, 5041, 1);
				break;
			case 10143:
				res = usePotion(playable, 2379, 1);
				usePotion(playable, 2380, 1);
				usePotion(playable, 2381, 1);
				usePotion(playable, 2382, 1);
				usePotion(playable, 2383, 1);
				break;
			case 10144:
				res = usePotion(playable, 2379, 1);
				usePotion(playable, 2380, 1);
				usePotion(playable, 2381, 1);
				usePotion(playable, 2384, 1);
				usePotion(playable, 2385, 1);
				break;
			case 10145:
				res = usePotion(playable, 2379, 1);
				usePotion(playable, 2380, 1);
				usePotion(playable, 2381, 1);
				usePotion(playable, 2384, 1);
				usePotion(playable, 2386, 1);
				break;
			case 10146:
				res = usePotion(playable, 2379, 1);
				usePotion(playable, 2387, 1);
				usePotion(playable, 2381, 1);
				usePotion(playable, 2388, 1);
				usePotion(playable, 2383, 1);
				break;
			case 10147:
				res = usePotion(playable, 2379, 1);
				usePotion(playable, 2387, 1);
				usePotion(playable, 2381, 1);
				usePotion(playable, 2383, 1);
				usePotion(playable, 2389, 1);
				break;
			case 10148:
				res = usePotion(playable, 2390, 1);
				usePotion(playable, 2391, 1);
				break;
			default:
		}

		if (res)
			playable.destroyItem("Consume", item.getObjectId(), 1, null, false);
	}

	/**
	 * @param activeChar
	 * @param effectType
	 * @param itemId
	 * @return
	 */
	private boolean isEffectReplaceable(L2Playable playable, Enum<L2EffectType> effectType, int itemId)
	{
		L2Effect[] effects = playable.getAllEffects();
		L2PcInstance activeChar = (L2PcInstance) ((playable instanceof L2PcInstance) ? playable : ((L2Summon) playable).getOwner());
		if (effects == null)
			return true;

		for (L2Effect e : effects)
		{
			if (e.getEffectType() == effectType)
			{
				// One can reuse pots after 2/3 of their duration is over.
				// It would be faster to check if its > 10 but that would screw custom pot durations...
				if (e.getTaskTime() > (e.getSkill().getBuffDuration() * 67) / 100000)
					return true;
				SystemMessage sm = new SystemMessage(SystemMessageId.S1_PREPARED_FOR_REUSE);
				sm.addItemName(itemId);
				activeChar.sendPacket(sm);
				return false;
			}
		}
		return true;
	}
	
	/**
	 * 
	 * @param activeChar
	 * @param magicId
	 * @param level
	 * @return
	 */
	public boolean usePotion(L2Playable activeChar, int magicId, int level)
	{

		L2Skill skill = SkillTable.getInstance().getInfo(magicId, level);

		if (skill != null)
		{
			if (!skill.checkCondition(activeChar, activeChar, false))
				return false;
			// Return false if potion is in reuse so it is not destroyed from inventory
			if (activeChar.isSkillDisabled(skill.getId()))
			{
				SystemMessage sm = new SystemMessage(SystemMessageId.S1_PREPARED_FOR_REUSE);
				sm.addSkillName(skill);
				activeChar.sendPacket(sm);
				return false;
			}
			if (skill.isPotion())
				activeChar.doSimultaneousCast(skill);
			else
				activeChar.doCast(skill);

			if (activeChar instanceof L2PcInstance)
			{
				L2PcInstance player = (L2PcInstance)activeChar;
				// Only for Heal potions
				if (magicId == 2031 || magicId == 2032 || magicId == 2037)
					player.shortBuffStatusUpdate(magicId, level, 15);

				if (!(player.isSitting() && !skill.isPotion()))
					return true;
			}
			else if (activeChar instanceof L2PetInstance)
			{
				SystemMessage sm = new SystemMessage(SystemMessageId.PET_USES_S1);
				sm.addString(skill.getName());
				((L2PetInstance)(activeChar)).getOwner().sendPacket(sm);
				return true;
			}
		}
		return false;
	}

	private void itemNotForPets(L2PcInstance activeChar)
	{
		activeChar.sendPacket(new SystemMessage(SystemMessageId.ITEM_NOT_FOR_PETS));
	}

	/**
	 * @see com.l2emu.gameserver.handler.IItemHandler#getItemIds()
	 */
	public int[] getItemIds()
	{
		return ITEM_IDS;
	}
}
